#include "req_handle.h"
#include "log_console.h"
#include <pthread.h>
#include <modbus.h>
#include <modbus-rtu.h>
#include <modbus-tcp.h>
#include <modbus-version.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <errno.h>
#include <sys/sem.h>
#include <stdio.h>
#include <sys/msg.h>
#include <shmem.h>
#include <msg_queue_peer.h>
#include <cJSON.h>
#include <list.h>

#define KB 1024
#define HTML_SIZE (64 * KB)

//普通的文本回复需要增加html头部
#define HTML_HEAD "Content-Type: text/html\r\n" \
				  "Connection: close\r\n"
#define JSON_HEAD "Content-Type: application/json\r\n" \
                  "Connection: close\r\n"

static struct shm_param para;
union val_t {
    int b_val;
    int i_val;
    float f_val;
};

struct std_node
{
    int key;             //唯一键值
    int type;            //数据点类型
    int dev_type;        //数据点属于哪个设备，根据网关支持的设备自行定义
    union val_t old_val; //变化上报后需要更新旧值
    union val_t new_val; //从共享内存取出最新数据，放到new_val中
    int ret;             //默认为-1，采集成功后设置为0，采集失败再置-1
};
struct msgbuf
{
    long mtype;
    int key;
    union val_t val;
    //char mdata[256];
};
struct msgjson
{
    int key;
    int type;
    int result;
    union val_t val;
};

/**
 * @brief 处理自定义请求，在这里添加进程通信
 * @param input
 * @return
 */
int parse_and_process(char *input)
{
    char val_buf[2048] = {0};
    char reply_buf[HTML_SIZE] = {0};
    struct msgjson msg_json;
    char *buf = NULL;
    strcpy(val_buf, input);
    log_console("input:::%s\n", input);
    log_console("val_buf:::%s\n", val_buf);
    //这里可以根据接收的数据请求进行处理
    /* 登录判断*/
    if(strncmp(val_buf,"username",8) == 0)
    {
        if(strcmp(val_buf, "username=admin&password=admin")==0)
        {
            strcpy(reply_buf, "<script>window.location.href = '/index.html';</script>");
            fputs(reply_buf, stdout);
        }
        else
        {
            strcpy(reply_buf, "<script charset='UTF-8'>alert('用户名或密码错误');</script>");
            strcat(reply_buf, "<script>window.location.href = '/login.html';</script>");
            fputs(reply_buf, stdout);
        }
    }
    
    /* JSON 解析*/
    cJSON *root = NULL, *data_array = NULL, *data = NULL;
    root = cJSON_Parse(val_buf); //将JSON字符串转换成JSON结构体
    if (root == NULL)
    {
        log_console("Error before: [%s]\n", cJSON_GetErrorPtr());
        return -1;
    }
    msg_json.type = cJSON_GetObjectItem(root, "type")->valueint;
    msg_json.result = cJSON_GetObjectItem(root, "type")->valueint;
    if(msg_json.type == 1)
    {
        //创建共享内存
        int ret = -1;
        ret = shm_init(&para, "shm_test", 2048);
        if (ret < 0)
        {
            return -1;
        }
        int *msg_num = shm_getaddr(&para);
        if (msg_num == NULL)
        {
            return -1;
        }
        log_console("num = %d\n", *msg_num);
        struct std_node *msg = msg_num + sizeof(int);
        /*JSON序列化 */
        root = cJSON_CreateObject();
        cJSON_AddNumberToObject(root, "type", 1);
        cJSON_AddNumberToObject(root, "result", 0);
        data = cJSON_CreateArray();
        cJSON_AddItemToObject(root, "data", data);
        for (int i = 0; i < *msg_num; i++)
        {
            data_array = cJSON_CreateObject();
            cJSON_AddNumberToObject(data_array, "key", msg[i].key);
            cJSON_AddNumberToObject(data_array, "val", msg[i].new_val.f_val);
            cJSON_AddItemToArray(data, data_array);
        }

        buf = cJSON_Print(root);
        // log_console("key:%d,type:%d,val:%.2f\n", msg[0].key, msg[0].type, msg[0].new_val.f_val);
        // log_console("key:%d,type:%d,val:%.2f\n", msg[1].key, msg[1].type, msg[1].new_val.f_val);
        // log_console("key:%d,type:%d,val:%.2f\n", msg[1].key, msg[1].type, msg[1].new_val.f_val);
        log_console("json:%s\n", buf);
        //shm_del(&para);
        cJSON_Delete(root);
    }
    else if(msg_json.type == 2)
    {
        int data_size;
        struct msgbuf send_buf;
        data = cJSON_GetObjectItem(root, "data");
        data_size = cJSON_GetArraySize(data);
        log_console("size:%d\n", data_size);
        send_buf.mtype = 'a';
        for (int i = 0; i < data_size; i++)
        {
            data_array = cJSON_GetArrayItem(data, i); //从数组中取
            //key值
            send_buf.key = atoi(cJSON_GetObjectItem(data_array, "key")->valuestring);
             //val值
            if(send_buf.key == 103)
            {
                send_buf.val.b_val = atoi(cJSON_GetObjectItem(data_array, "val")->valuestring);
                if(msg_queue_send("msga", &send_buf, sizeof(send_buf), 0) < 0)
                {
                    log_console("msg_queue_send error\n");
                    return -1;
                }
            }
            else if(send_buf.key == 104)
            {
                send_buf.val.f_val = atof(cJSON_GetObjectItem(data_array, "val")->valuestring);
                if(msg_queue_send("msga", &send_buf, sizeof(send_buf), 0) < 0)
                {
                    log_console("msg_queue_send error\n");
                    return -1;
                }
            }
            else if(send_buf.key == 105)
            {
                send_buf.val.b_val = atoi(cJSON_GetObjectItem(data_array, "val")->valuestring);
                if(msg_queue_send("msga", &send_buf, sizeof(send_buf), 0) < 0)
                {
                    log_console("msg_queue_send error\n");
                    return -1;
                }
            }
        }
        root = cJSON_CreateObject();
        cJSON_AddNumberToObject(root, "type", 1);
        cJSON_AddNumberToObject(root, "result", 0);
        buf = cJSON_Print(root);
        log_console("json:%s\n", buf);
        cJSON_Delete(root);
    }

	//数据处理完成后，需要给服务器回复，回复内容按照http协议格式
    sprintf(reply_buf, "%sContent-Length: %ld\r\n\r\n", JSON_HEAD, strlen(buf));
    strcat(reply_buf, buf);
    log_console("post json_str = %s", reply_buf);
	
	//向标准输出写内容（标准输出服务器已做重定向）
    fputs(reply_buf, stdout);
    return 0;
}
